from Configs import APCP_SIGNAL_ID_PATH
from Configs import APCP_NORMAL_HEADER_PATH
from Configs import APCP_TIMESYNC_HEADER_PATH
from Configs import APCP_AVAS_HEADER_PATH
from Configs import APCP_HOSTINFO_HEADER_PATH
from Configs import APCP_POWER_HEADER_PATH

from Configs import APCP_TRANSFER_HEADER_PATH
from Configs import APCP_SIGNAL_HEADER_PATH
from Configs import APCP_SIGNAL_CPP_PATH
from Configs import APCP_CONVERT_IPCP_PATH
from Configs import APCP_CONVERT_FROM_IPCP_PATH
from Configs import SIGNAL_CP

from Configs import WRITE
from Configs import READ
from Configs import SHEET_NAME_NORMAL
from Configs import SHEET_NAME_TimeSync
from Configs import SHEET_NAME_AVAS
from Configs import SHEET_NAME_HOSTINFO
from Configs import SHEET_NAME_POWER
from Configs import STRING
from Configs import BOOLEAN
from Configs import INT32
from Configs import INT32_VEC
from Configs import INT64
from Configs import INT64_VEC
from Configs import FLOAT
from Configs import FLOAT_VEC
from Configs import BYTES

from Elements import Element

from Configs import EXTRA_KEY_PULL

import Template

from Elements import PayloadType
from Elements import Direction

import json

TX_INDEX = 1
RX_INDEX = 1


# =======================================================
def readApCpSignalId():
    return open(APCP_SIGNAL_ID_PATH, "w", encoding="UTF-8")

def readNormalHeader():
    return open(APCP_NORMAL_HEADER_PATH, "w", encoding="UTF-8")

def readTimeSyncHeader():
    return open(APCP_TIMESYNC_HEADER_PATH, "w", encoding="UTF-8")

def readAVASHeader():
    return open(APCP_AVAS_HEADER_PATH, "w", encoding="UTF-8")

def readHostInfoHeader():
    return open(APCP_HOSTINFO_HEADER_PATH, "w", encoding="UTF-8")

def readPowerHeader():
    return open(APCP_POWER_HEADER_PATH, "w", encoding="UTF-8")

def readAPCPTransferHeader():
    return open(APCP_TRANSFER_HEADER_PATH, "w", encoding="UTF-8")


def readAPCPSignalHeader():
    return open(APCP_SIGNAL_HEADER_PATH, "w", encoding="UTF-8")


def readAPCPSignalCpp():
    return open(APCP_SIGNAL_CPP_PATH, "w", encoding="UTF-8")


def readConvert2IPCP():
    return open(APCP_CONVERT_IPCP_PATH, "w", encoding="UTF-8")

def readConvertFromIPCP():
    return open(APCP_CONVERT_FROM_IPCP_PATH, "w", encoding="UTF-8")


# =======================================================
# APCP_Signal_Id.h
# Step1 : write file header
def writeSignalIdHeader(file, isCPP=False):
    file.write(Template.TPL_SIGNAL_ID_HEADER if not isCPP else Template.TPL_SIGNAL_ID_HEADER_CPP)


# Step2 : write tx signals , call for all module
def writeSignalIdTX(file, list):
    global TX_INDEX
    for element in list:
        file.write(
            Template.TPL_SIGNAL_ID
                .replace("_NOTE", element.mDescription.replace("\n", "\n         *                "))
                .replace("_ENCODE_TYPE", element.mPayloadStr)
                .replace("_SWRS_NAME", element.mSWRSName)
                .replace("_SIGNAL_VALVE_STRING",
                         str("%#05x" % TX_INDEX) + " | SIGNAL_CP | WRITE | " + element.getPayloadConfigStr())
                .replace("_SIGNAL_NAME", element.mName)
                .replace("_SIGNAL_VALUE_HEX",
                         str("%#x" % (TX_INDEX | SIGNAL_CP | WRITE | element.getPayloadConfigValue())))
        )
        TX_INDEX += 1


# Step3 : write file tx rx divider
def writeSignalIdTxRxDivider(file):
    file.write(Template.TPL_SIGNAL_TX_RX_DIVIDER)


# Step4 : write rx signals , call for all module
def writeSignalIdRX(file, list, isCPP=False):
    global RX_INDEX
    for element in list:
        file.write(
            Template.TPL_SIGNAL_ID
                .replace("_NOTE", element.mDescription.replace("\n", "\n         *                "))
                .replace("_ENCODE_TYPE", element.mPayloadStr)
                .replace("_SWRS_NAME", element.mSWRSName)
                .replace("_SIGNAL_VALVE_STRING",
                         str("%#05x" % RX_INDEX) + " | SIGNAL_CP | READ | " + element.getPayloadConfigStr())
                .replace("_SIGNAL_NAME", element.mName)
                .replace("_SIGNAL_VALUE_HEX",
                         str("%#x" % (RX_INDEX | SIGNAL_CP | READ | element.getPayloadConfigValue())))
        )
        RX_INDEX += 1


# Step5 : write file sdb divider
def writeSignalIDEnumsDivider(file):
    file.write(Template.TPL_SIGNAL_ENUMS_DIVIDER)


# Step6 : write file sdb enums
def writeSignalIdEnums(file, listTextTable, listExtra):
    # 确认和sdb冲突的部分
    dictSdb = {}
    for element in listExtra:
        dictSdb.update({element.mPayloadStr: 0})
    # .............
    textContent = Template.TPL_ENUM
    tableNameLast = ""
    for element in listTextTable:
        # TextTableName.ValueName
        textMix = element.mName.split(".")
        # valueNum
        value = element.mPayloadStr
        # SDB冲突部分不生成
        if dictSdb.__contains__(textMix[0]):
            continue
        if len(tableNameLast) > 0 and tableNameLast != textMix[0]:
            file.write(textContent.replace("\nENUM_MEMBER", ""))
            textContent = Template.TPL_ENUM
        # 把注释给加上
        note = "" if len(element.mDescription) == 0 and len(element.mSWRSName) == 0 \
            else ("//" + element.mDescription + ("" if len(element.mSWRSName) == 0 else "(" + element.mSWRSName + ")"))
        textContent = textContent \
            .replace("ENUM_NAME", textMix[0]) \
            .replace("ENUM_MEMBER", "            " +
                     textMix[1] +
                     " = " +
                     value +
                     "," +
                     note +
                     "\nENUM_MEMBER")
        tableNameLast = textMix[0]
    file.write(textContent.replace("\nENUM_MEMBER", ""))


# Step7 : write foot ,end
def writeSignalIdFoot(file):
    file.write(Template.TPL_SIGNAL_FOOT)


# =======================================================

def writeHeaderPragma(file):
    file.write(Template.TPL_PRAGMA)


def writeHeaderOpCode(file, listTX, listRX):
    file.write("\n")
    for element in listTX:
        file.write(
            Template.TPL_OPCODE.replace("_SIGNAL", element.mName)
                .replace("_VALUE", str("%#x" % element.mOpCode))
        )
    file.write("\n")
    for element in listRX:
        file.write(
            Template.TPL_OPCODE.replace("_SIGNAL", element.mName)
                .replace("_VALUE", str("%#x" % element.mOpCode))
        )


def writeHeaderStruct(file, listTX, listRX, listStruct):
    # ------其实TX和RX其它代码是复制的-------
    # 写入TX结构体
    for element in listTX:
        # 针对struct
        if element.mPayloadType == PayloadType.struct:
            # 准备写入struct
            content = Template.TPL_STRUCT_TX
            _find = False
            # 暂时为空结构体的暂时生成空结构体
            if element.mPayloadStr == "None" or element.mPayloadStr == "none":
                file.write(
                    content.replace("_SIGNAL", element.mName)
                        .replace("\n    _PAYLOAD_t _VALUE;", "\n    // empty")
                )
                continue
            # 遍历找寻结构体
            for structElement in listStruct:
                structMix = structElement.mName.split(".")
                if structMix[0] != element.mPayloadStr:
                    if _find:# 数据为顺序,已经写入过且不一样,则为下一个结构体
                        file.write(content.replace("\n    _PAYLOAD_t _VALUE;", ""))
                        content = Template.TPL_STRUCT_TX
                        break
                    else:
                        continue
                _find = True
                # 确认是否有注释
                note = "// " + structElement.mDescription + \
                       ("" if len(structElement.mPayloadStr) == 0
                              or structElement.mPayloadStr == "None"
                              or structElement.mPayloadStr == "none" else "(" + structElement.mPayloadStr + ")")
                content = content.replace("_SIGNAL", element.mName) \
                    .replace("_PAYLOAD_t _VALUE;",
                             structElement.mPayloadType.name +
                             "_t m" +
                             structMix[1] + ";" +
                             note +
                             "\n    _PAYLOAD_t _VALUE;")
            # 最后一个结构体写入
            if content != Template.TPL_STRUCT_TX:
                file.write(content.replace("\n    _PAYLOAD_t _VALUE;", ""))
        elif element.mPayloadType == PayloadType.bytes:
            continue
        else:
            file.write(Template.TPL_STRUCT_TX
                       .replace("_SIGNAL", element.mName)
                       .replace("_PAYLOAD", element.mPayloadType.name)
                       .replace("_VALUE", "value;" +
                                ("" if len(element.mDescription) == 0 and len(element.mPayloadStr)
                                 else ("// " + element.mDescription.replace("\n", ",") +
                                       ("" if len(element.mPayloadStr) == 0
                                        else "(" + element.mPayloadStr + ")")))))
    # 写入RX结构体
    for element in listRX:
        # 针对struct
        if element.mPayloadType == PayloadType.struct:
            # 准备写入struct
            content = Template.TPL_STRUCT_RX
            _find = False
            # 暂时为空结构体的暂时生成空结构体
            if element.mPayloadStr == "None" or element.mPayloadStr == "none":
                file.write(
                    content.replace("_SIGNAL", element.mName)
                        .replace("\n    _PAYLOAD_t _VALUE;", "\n    // empty")
                )
                continue
            # 遍历找寻结构体
            for structElement in listStruct:
                structMix = structElement.mName.split(".")
                if structMix[0] != element.mPayloadStr:
                    if _find:# 数据为顺序,已经写入过且不一样,则为下一个结构体
                        file.write(content.replace("\n    _PAYLOAD_t _VALUE;", ""))
                        content = Template.TPL_STRUCT_RX
                        break
                    else:
                        continue
                _find = True
                # 确认是否有注释
                note = "// " + structElement.mDescription + \
                       ("" if len(structElement.mPayloadStr) == 0
                              or structElement.mPayloadStr == "None"
                              or structElement.mPayloadStr == "none" else "(" + structElement.mPayloadStr + ")")
                content = content.replace("_SIGNAL", element.mName) \
                    .replace("_PAYLOAD_t _VALUE;",
                             structElement.mPayloadType.name + "_t m" +
                             structMix[1] +
                             ";" +
                             note +
                             "\n    _PAYLOAD_t _VALUE;")
            # 最后一个结构体写入
            if content != Template.TPL_STRUCT_RX:
                file.write(content.replace("\n    _PAYLOAD_t _VALUE;", ""))
        # 针对其它类型(后续可能需要改造)
        else:
            file.write(Template.TPL_STRUCT_RX
                       .replace("_SIGNAL", element.mName)
                       .replace("_PAYLOAD", element.mPayloadType.name)
                       .replace("_VALUE", "value;" +
                                ("" if len(element.mDescription) == 0 and len(element.mPayloadStr)
                                 else ("// " + element.mDescription.replace("\n", ",") +
                                       ("" if len(element.mPayloadStr) == 0
                                        else "(" + element.mPayloadStr + ")")))))


def getlistStr(listElement, ipcp_extra, seatStr):
    opCodeStr = ""
    endCode = 0
    for i in range(len(listElement) + ipcp_extra):
        element = Element()
        if i < len(listElement):
            element = listElement[i]
        # ---------------------------------------------------
        # 防止IPCP版本间差异过大,未注册OpCode,导致程序异常,多注册{ipcp_extra}}个
        if element.mOpCode == 0:
            element.mOpCode = endCode + 1
        endCode = element.mOpCode
        # ---------------------------------------------------
        opCodeStr += str("%#x" % element.mOpCode) + \
                     ("," if (i < len(listElement) + ipcp_extra - 1) else "") + \
                     (("\n" + seatStr) if (
                             i > 0 and (i + 1) % 10 == 0 and i < (len(listElement) + ipcp_extra - 1)) else "")

    return opCodeStr


def writeHeaderOpIds(file,
                     listNormalTX, listNormalRX,
                     listTimeSyncTX, listTimeSyncRX,
                     listAvasTX, listAvasRX,
                     listHostInfoTX, listHostInfoRX,
                     listPowerTX, listPowerRX):
    # 防止IPCP版本间差异过大,未注册OpCode,导致程序异常,多注册{ipcp_extra}}个
    IPCP_EXTRA = 0
    # --------------------- Normal ---------------------
    normalOpIds = ""
    normalSeatStr = "                                     "
    normalOpIds += getlistStr(listNormalTX, IPCP_EXTRA, normalSeatStr)
    normalOpIds += ",\n" + normalSeatStr
    normalOpIds += getlistStr(listNormalRX, IPCP_EXTRA, normalSeatStr)
    # --------------------- TimeSync ---------------------
    timeSyncOpIds = ""
    timeSyncSeatStr = "                                       "
    timeSyncOpIds += getlistStr(listTimeSyncTX, IPCP_EXTRA, timeSyncSeatStr)
    timeSyncOpIds += ",\n" + timeSyncSeatStr
    timeSyncOpIds += getlistStr(listTimeSyncRX, IPCP_EXTRA, timeSyncSeatStr)
    # --------------------- AVAS ---------------------
    avasSyncOpIds = ""
    avasSyncSeatStr = "                                   "
    avasSyncOpIds += getlistStr(listAvasTX, IPCP_EXTRA, avasSyncSeatStr)
    avasSyncOpIds += ",\n" + avasSyncSeatStr
    avasSyncOpIds += getlistStr(listAvasRX, IPCP_EXTRA, avasSyncSeatStr)
    # --------------------- HostInfo ---------------------
    hostInfoSyncOpIds = ""
    hostInfoSyncSeatStr = "                                   "
    hostInfoSyncOpIds += getlistStr(listHostInfoTX, IPCP_EXTRA, hostInfoSyncSeatStr)
    hostInfoSyncOpIds += ",\n" + hostInfoSyncSeatStr
    hostInfoSyncOpIds += getlistStr(listHostInfoRX, IPCP_EXTRA, hostInfoSyncSeatStr)
    # --------------------- Power ---------------------
    powerSyncOpIds = ""
    powerSyncSeatStr = "                                   "
    powerSyncOpIds += getlistStr(listPowerTX, IPCP_EXTRA, powerSyncSeatStr)
    powerSyncOpIds += ",\n" + powerSyncSeatStr
    powerSyncOpIds += getlistStr(listPowerRX, IPCP_EXTRA, powerSyncSeatStr)
    file.write(Template
               .TPL_APCP_TRANSFER_HEADER
               .replace("NORMAL_OP_IDS", normalOpIds)
               .replace("TIMESYNC_OP_IDS", timeSyncOpIds)
               .replace("AVAS_OP_IDS", avasSyncOpIds)
               .replace("HOSTINFO_OP_IDS", hostInfoSyncOpIds)
               .replace("POWER_OP_IDS", powerSyncOpIds)
               .replace("NORMAL_OP_NUM", str((len(listNormalTX) + IPCP_EXTRA + len(listNormalRX) + IPCP_EXTRA)))
               .replace("TIMESYNC_OP_NUM", str((len(listTimeSyncTX) + IPCP_EXTRA + len(listTimeSyncRX) + IPCP_EXTRA)))
               .replace("AVAS_OP_NUM", str((len(listAvasTX) + IPCP_EXTRA + len(listAvasRX) + IPCP_EXTRA)))
               .replace("HOSTINFO_OP_NUM", str((len(listHostInfoTX) + IPCP_EXTRA + len(listHostInfoRX) + IPCP_EXTRA)))
               .replace("POWER_OP_NUM", str((len(listPowerTX) + IPCP_EXTRA + len(listPowerRX) + IPCP_EXTRA)))
               )


def write_Signal_h_Front(file):
    file.write(Template.TPL_SIGNAL_H_FRONT)


def write_Signal_h_Typedef(file, listTX, listRX):
    for element in listTX:
        if element.mPayloadType != PayloadType.bytes:
            file.write("typedef OpSIGNAL_NAME_SetRequestNoReturn SIGNAL_NAME;\n"
                       .replace("SIGNAL_NAME", element.mName))
    for element in listRX:
        file.write("typedef OpSIGNAL_NAME_Notify SIGNAL_NAME;\n"
                   .replace("SIGNAL_NAME", element.mName))


def write_Signal_h_Body(file):
    file.write(Template.TPL_SIGNAL_H_BODY)


def write_Signal_h_Function(file, listTX, listRX, listSDB):
    for element in listTX:
        if element.mPayloadType == PayloadType.bytes:
            show_payload_str = "std::vector<uint8_t>"
            actual_payload_str = element.mName
            show_value_str = "value"
        elif element.mPayloadType == PayloadType.struct:
            show_payload_str = element.mName
            actual_payload_str = element.mName
            show_value_str = "value"
        elif (element.mPayloadStr != "None" and element.mPayloadStr != "none"):
            show_payload_str = "sdb::" + element.mPayloadStr
            actual_payload_str = "sdb::" + element.mPayloadStr
            show_value_str = "value"
        else:
            show_payload_str = element.mPayloadType.name + "_t"
            actual_payload_str = "sdb::" + element.mPayloadStr
            show_value_str = element.mPayloadStr.lower()
        for elementSdb in listSDB:
            if element.mPayloadStr == elementSdb.mPayloadStr:
                show_payload_str = element.mPayloadType.name + "_t"
                show_value_str = element.mPayloadStr.lower()
        file.write(
            Template.TPL_SIGNAL_H_SET_FUNC
                .replace("SIGNAL_NAME", element.mName)
                .replace("PAYLOAD_NAME", show_payload_str)
                .replace("FUNCTION_NOTE", element.mDescription.replace("\n", "\n        * "))
                .replace("VALUE_NOTE", actual_payload_str)
                .replace("SHOW_VALUE", show_value_str)
        )
    for element in listRX:
        if element.mPayloadType == PayloadType.struct:
            show_payload_str = element.mName
            actual_payload_str = element.mName
            show_value_str = "value"
        elif (element.mPayloadStr != "None" and element.mPayloadStr != "none"):
            show_payload_str = "sdb::" + element.mPayloadStr
            actual_payload_str = "sdb::" + element.mPayloadStr
            show_value_str = "value"
        else:
            show_payload_str = "int32_t"
            actual_payload_str = "sdb::" + element.mPayloadStr
            show_value_str = element.mPayloadStr.lower()
        for elementSdb in listSDB:
            if element.mPayloadStr == elementSdb.mPayloadStr:
                show_payload_str = "int32_t"
                show_value_str = element.mPayloadStr.lower()
        file.write(
            Template.TPL_SIGNAL_H_GET_FUNC
                .replace("SIGNAL_NAME", element.mName)
                .replace("PAYLOAD_NAME", show_payload_str)
                .replace("FUNCTION_NOTE", element.mDescription.replace("\n", "\n        * "))
                .replace("VALUE_NOTE", actual_payload_str)
                .replace("SHOW_VALUE", show_value_str)
        )


def write_Signal_h_End(file):
    file.write(Template.TPL_SIGNAL_H_END)


def addSignalIds(listRel, listSrc, listStruct, listPull):
    memDict = {}
    for pull_element in listPull:
        if pull_element.mName == EXTRA_KEY_PULL:
            memDict.update({pull_element.mPayloadStr: 0})
    for data_element in listSrc:
        if data_element.mPayloadType == PayloadType.struct \
                and memDict.__contains__(data_element.mPayloadStr):
            for element in listStruct:
                # StructName.MemberName
                structMix = element.mName.split(".")
                if data_element.mPayloadStr == structMix[0] \
                        and memDict.__contains__(structMix[0]):
                    newElement = Element()
                    newElement.setSheetName(element.mSheetName)
                    newElement.setName(structMix[1])
                    newElement.setModule(element.mModule)
                    newElement.setDirection(element.mDirection.name)
                    newElement.setServiceType(element.mServiceType.name)
                    newElement.setOpType(element.mOpType)
                    newElement.setOpCode(str(element.mOpCode))
                    newElement.setPayloadType(element.mPayloadType.name)
                    newElement.setPayloadStr(element.mPayloadStr)
                    newElement.setDescription(element.mDescription + "(" + element.mName + ")")
                    newElement.setPackage(element.mPackage)
                    newElement.setSWRSName(element.mSWRSName)
                    listRel.append(newElement)
        else:
            listRel.append(data_element)


def write_Signal_cpp_Front(file):
    file.write(Template.TPL_SIGNAL_CPP_FRONT)


def write_Signal_cpp_Function(file, listTX, listRX, listSDB):
    for element in listTX:
        if element.mPayloadType == PayloadType.bytes:
            show_payload_str = "std::vector<uint8_t>"
            actual_payload_str = element.mName
            show_value_str = "value"
            template_Str = Template.TPL_SIGNAL_CPP_FUNC_SET_BYTE_VEC
        elif element.mPayloadType == PayloadType.struct:
            show_payload_str = element.mName
            actual_payload_str = element.mName
            show_value_str = "value"
            template_Str = Template.TPL_SIGNAL_CPP_FUNC_SET_BYTE
        elif (element.mPayloadStr != "None" and element.mPayloadStr != "none"):
            show_payload_str = "sdb::" + element.mPayloadStr
            actual_payload_str = "sdb::" + element.mPayloadStr
            show_value_str = "value"
            template_Str = Template.TPL_SIGNAL_CPP_FUNC_SET_INT
        else:
            show_payload_str = element.mPayloadType.name + "_t"
            actual_payload_str = "sdb::" + element.mPayloadStr
            show_value_str = element.mPayloadStr.lower()
            template_Str = Template.TPL_SIGNAL_CPP_FUNC_SET_INT
        for elementSdb in listSDB:
            if element.mPayloadStr == elementSdb.mPayloadStr:
                show_payload_str = element.mPayloadType.name + "_t"
                show_value_str = element.mPayloadStr.lower()
                template_Str = Template.TPL_SIGNAL_CPP_FUNC_SET_INT
        file.write(
            template_Str
                .replace("SIGNAL_NAME", element.mName)
                .replace("PAYLOAD_NAME", show_payload_str)
                .replace("FUNCTION_NOTE", element.mDescription.replace("\n", "\n        * "))
                .replace("VALUE_NOTE", actual_payload_str)
                .replace("SHOW_VALUE", show_value_str)
        )
    for element in listRX:
        if element.mPayloadType == PayloadType.struct:
            show_payload_str = element.mName
            actual_payload_str = element.mName
            show_value_str = "value"
            template_Str = Template.TPL_SIGNAL_CPP_FUNC_GET_BYTES
        elif (element.mPayloadStr != "None" and element.mPayloadStr != "none"):
            show_payload_str = "sdb::" + element.mPayloadStr
            actual_payload_str = "sdb::" + element.mPayloadStr
            show_value_str = "value"
            template_Str = Template.TPL_SIGNAL_CPP_FUNC_GET_ENUM
        else:
            show_payload_str = "int32_t"
            actual_payload_str = "sdb::" + element.mPayloadStr
            show_value_str = element.mPayloadStr.lower()
            template_Str = Template.TPL_SIGNAL_CPP_FUNC_GET_INT
        for elementSdb in listSDB:
            if element.mPayloadStr == elementSdb.mPayloadStr:
                show_payload_str = "int32_t"
                show_value_str = element.mPayloadStr.lower()
                template_Str = Template.TPL_SIGNAL_CPP_FUNC_GET_INT
        file.write(
            template_Str
                .replace("SIGNAL_NAME", element.mName)
                .replace("PAYLOAD_NAME", show_payload_str)
                .replace("FUNCTION_NOTE", element.mDescription.replace("\n", "\n        * "))
                .replace("VALUE_NOTE", actual_payload_str)
                .replace("SHOW_VALUE", show_value_str)
        )


def write_Signal_cpp_End(file):
    file.write(Template.TPL_SIGNAL_CPP_END)


def write_2_ipcp_front(file):
    file.write(Template.TPL_TO_IPCP_FRONT)


def write_2_ipcp_case(file, list):
    for element in list:
        if element.mPayloadType == PayloadType.struct:
            template_str = Template.TPL_TO_IPCP_BYTES
        elif element.mPayloadType == PayloadType.bytes:
            template_str = Template.TPL_TO_IPCP_VEC_BYTES
        else:
            template_str = Template.TPL_TO_IPCP_INT32
        file.write(
            template_str.replace("SIGNAL_NAME", element.mName)
                .replace("SERVICE_ID", getName4ServiceId(element.mSheetName))
                .replace("OP_ID", element.mName + "OpId")
                .replace("SERVICE_PORT", getName4Port(element.mSheetName))
        )


def write_2_ipcp_end(file):
    file.write(Template.TPL_TO_IPCP_END)


def write_2_signal_front(file):
    file.write(Template.TPL_TO_SIGNAL_FRONT)


def write_convert_RX_signal_case(file, list, listStruct, listPull):
    memDict = {}
    for pull_element in listPull:
        if pull_element.mName == EXTRA_KEY_PULL:
            memDict.update({pull_element.mPayloadStr: 0})
    for data_element in list:
        if data_element.mPayloadType == PayloadType.struct:
            template_str = Template.TPL_TO_SIGNAL_BYTE
        else:
            template_str = Template.TPL_TO_SIGNAL_INT32
        # 单独处理结构体
        if data_element.mPayloadType == PayloadType.struct \
                and memDict.__contains__(data_element.mPayloadStr):
            size = 0
            emplace_Str = ""
            for element in listStruct:
                # StructName.MemberName
                structMix = element.mName.split(".")
                if data_element.mPayloadStr == structMix[0] \
                        and memDict.__contains__(structMix[0]):
                    size += 1
                    emplace_Str += Template.TPL_TO_SIGNAL_EMPLACE.replace("MEMBER_NAME", structMix[1])
            file.write(
                Template.TPL_TO_SIGNAL_BYTE_PULL.replace("EMPLACE_CONTENT", emplace_Str)
                    .replace("MEMBER_SIZE", str(size))
                    .replace("SIGNAL_NAME", data_element.mName)
                    .replace("SERVICE_ID", getName4ServiceId(data_element.mSheetName))
                    .replace("OP_ID", data_element.mName + "OpId")
                    .replace("SERVICE_PORT", getName4Port(data_element.mSheetName))
            )
        # 正常情况
        else:
            file.write(
                template_str.replace("SIGNAL_NAME", data_element.mName)
                    .replace("SERVICE_ID", getName4ServiceId(data_element.mSheetName))
                    .replace("OP_ID", data_element.mName + "OpId")
                    .replace("SERVICE_PORT", getName4Port(data_element.mSheetName))
                    .replace("MEMBER_SIZE", "1")
            )

def write_2_signal_end(file):
    file.write(Template.TPL_TO_SIGNAL_END)


def getName4ServiceId(name: str):
    if name == SHEET_NAME_NORMAL:
        return "CP_serviceID_Normal"
    elif name == SHEET_NAME_TimeSync:
        return "CP_serviceID_TimeSync"
    elif name == SHEET_NAME_AVAS:
        return "CP_serviceID_AVAS"
    elif name == SHEET_NAME_HOSTINFO:
        return "CP_serviceID_HostInfo"
    elif name == SHEET_NAME_POWER:
        return "CP_serviceID_Power"
    else:
        return "ERROR"


def getName4Port(name: str):
    if name == SHEET_NAME_NORMAL:
        return "CP_SERVICE_NORMAL_PORT"
    elif name == SHEET_NAME_TimeSync:
        return "CP_SERVICE_TIME_PORT"
    elif name == SHEET_NAME_AVAS:
        return "CP_SERVICE_AVAS_PORT"
    elif name == SHEET_NAME_HOSTINFO:
        return "CP_SERVICE_HOSTINFO_PORT"
    elif name == SHEET_NAME_POWER:
        return "CP_SERVICE_POWER_PORT"
    else:
        return "ERROR"

def getStructConfig(structName, listStruct, listTextable):
    configStruct = {}
    configStruct["name"] = structName
    member=[]
    find = False
    for element in listStruct:
        mix = element.mName.split(".")
        struct_name = mix[0] if not mix[0].__contains__("[") else int(mix[0].split("[")[0])
        if struct_name == structName or (find and struct_name == ""):
            find = True
            member_name = "m" + mix[1] if not mix[1].__contains__("[") else mix[1].split("[")[0]
            member_length = 0 if not mix[1].__contains__("[") else int(mix[1].split("[")[1].replace("]",""))
            if element.mPayloadStr == "none" or element.mPayloadStr == "None":
                member.append({
                    "name": member_name,
                    "arrayLen": member_length,
                    "type": element.getPayloadConfigValueInt(),
                    "desc": ""
                })
            else:
                member.append({
                    "name": member_name,
                    "arrayLen": member_length,
                    "type": element.getPayloadConfigValueInt(),
                    "enumDefine": getTextTableConfig(element.mPayloadStr, listTextable),
                    "desc": ""
                })
        elif find:
            break
    configStruct["fields"]=member
    return configStruct


def getTextTableConfig(textTableName, listTextable):
    configTextTable = {}
    configTextTable["name"] = textTableName
    find = False
    tableItems = []
    for element in listTextable:
        mix = element.mName.split(".")
        key =  mix[0]
        name = mix[1]
        value = int(element.mPayloadStr)
        if key == textTableName:
            find = True
            tableItems.append({"name": name, "value": value})
        elif find:
            break
    configTextTable["items"] = tableItems
    return configTextTable

def write_Signal_config_json(file,listTX,listRX,listStruct,listTextable):
    signalConfigs = []
    for element in listTX:
        # print("value : " + element.mSignalValue)
        config={}
        config["id"] = {"name": element.mName +
                                ("" if element.mSWRSName == "" else ("(" + element.mSWRSName + ")")),
                        "value": element.mSignalValue}
        config["module"] = element.mSheetName
        config["readOnly"] = False
        config["valueType"] = element.getPayloadConfigValue()
        config["notifyMode"] = 0
        if element.mPayloadType == PayloadType.struct:
            config["structDefine"] = getStructConfig(element.mPayloadStr, listStruct, listTextable)
        elif element.mPayloadStr != "None" or element.mPayloadStr != "none":
            config["enumDefine"] = getTextTableConfig(element.mPayloadStr, listTextable)
        config["description"] = ""
        signalConfigs.append(config)
    # 复制粘贴上面的，理论可以少写一遍
    for element in listRX:
        # print("value : " + element.mSignalValue)
        config={}
        config["id"] = {"name": element.mName +
                                ("" if element.mSWRSName == "" else ("(" + element.mSWRSName + ")")),
                        "value": element.mSignalValue}
        config["module"] = element.mSheetName
        config["readOnly"] = True
        config["valueType"] = element.getPayloadConfigValue()
        config["notifyMode"] = 0
        if element.mPayloadType == PayloadType.struct:
            config["structDefine"] = getStructConfig(element.mPayloadStr, listStruct, listTextable)
        elif element.mPayloadStr != "None" or element.mPayloadStr != "none":
            config["enumDefine"] = getTextTableConfig(element.mPayloadStr,listTextable)
        else:
            print("单纯值的类型不知道写什么")
        config["description"] = ""
        signalConfigs.append(config)
    # for element in listTX:
    #     print("value : " + element.mSignalValue)
    # config={}
    # config["id"]={"name":element.mName,
    #               "value":element}
    file.write(json.dumps(signalConfigs,indent=4))

